package com.apobates.forum.member.dao;

import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.entity.MemberStatusEnum;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Stream;

/**
 * 会员的持久层接口
 *
 * @author xiaofanku
 * @since 20200510
 */
public interface MemberDao {
    /**
     * 创建新的会员
     *
     * @param member 会员属性实例
     */
    void save(Member member);
    
    /**
     * 根据会员的登录帐号模糊查询会员
     *
     * @param namesWordChar 会员帐号的字符
     * @param showSize 显示的数量
     * @return
     */
    Stream<Member> searchByNames(String namesWordChar, int showSize);
    
    /**
     * 根据会员的登录帐号模糊查询会员
     *
     * @param namesWordChar 会员帐号的字符
     * @return
     */
    Stream<Member> searchByNames(String namesWordChar);
    
    /**
     * 查看指定集合的会员信息
     *
     * @param idList
     * @return
     */
    Stream<Member> findAllByIdList(List<Long> idList);
    
    /**
     * 查看最近注册的会员
     *
     * @param size 显示的数量
     * @return
     */
    Stream<Member> findAllOfRecent(int size);
    
    /**
     * 查看指定的会员
     *
     * @param memberNames 会员的登录帐号
     * @param encryptPswd 加密后的登录密码
     * @return
     */
    Optional<Member> findOne(String memberNames, String encryptPswd);
    
    /**
     * 查看指定的管理员
     *
     * @param memberNames
     * @param encryptPswd
     * @return
     */
    Optional<Member> findOneForAdmin(String memberNames, String encryptPswd);
    
    /**
     * [Cacheable]查看指定的会员
     *
     * @param memberId 会员ID
     * @return
     */
    Member findOneById(long memberId);
    
    /**
     * 更新会员的状态
     *
     * @param status Key = 会员ID, Value = 更新的会员状态
     * @return
     */
    int editMemberStatus(Map<Long, MemberStatusEnum> status);

    /**
     * 将指定的会员的组更新为MemberGroupEnum.CARD
     *
     * @param updateMemberIds 更新的会员ID集合
     * @return
     */
    int editMemberGroup(Set<Long> updateMemberIds);

    /**
     * 查看会员的头像
     *
     * @param id 会员ID
     * @return
     */
    Optional<String> getAvatar(long id);
    
    /**
     * 会员登录的帐号是否存在
     *
     * @param memberNames 会员登录帐号
     * @return 如果存在返回会员当前的密码盐
     */
    Optional<String> findSalt(String memberNames);
    
    /**
     * 查看指定的会员是否存在
     *
     * @param id 会员ID
     * @return 如果存在返回会员当前的密码盐
     */
    Optional<String> findSalt(long id);
    
    /**
     * 更新会员的头像地址
     *
     * @param id 会员ID
     * @param encodeAvatarPath 编码后的头像地址
     * @return
     */
    Optional<Boolean> editAvatar(long id, String encodeAvatarPath);
    
    /**
     * 更新会员的昵称和签名
     *
     * @param id 会员ID
     * @param nickname 会员昵称
     * @param signature 会员签名
     * @return
     */
    Optional<Boolean> editNicknameAndSignature(long id, String nickname, String signature);
    
    /**
     * 更新会员的管理角色
     *
     * @param memberId 会员ID
     * @param role 角色
     * @return
     */
    boolean editMemberRole(long memberId, MemberRoleEnum role);
    
    /**
     * 更新会员的组
     *
     * @param memberId 会员ID
     * @param group 会员组
     * @return
     */
    boolean editMemberGroup(long memberId, MemberGroupEnum group);
    
    /**
     * 更新会员的状态
     *
     * @param memberId 会员ID
     * @param status 更新的会员状态
     * @return
     */
    boolean editMemberStatus(long memberId, MemberStatusEnum status);
    
    /**
     * 会员登录的帐号是否存在
     *
     * @param memberNames 会员登录帐号
     * @return 存在返回会员ID,不存在返回0,参数不可用返回-1
     */
    long exists(String memberNames);
    
    /**
     * 更新会员的登录密码
     *
     * @param id 会员ID
     * @param oldEncryptPswd 现在使用的密码,加密后的
     * @param newEncryptPswd 更新的新密码,加密后的
     * @param newPswdSalt 更新密码使用的盐
     * @return
     */
    int editPswd(long id, String oldEncryptPswd, String newEncryptPswd, String newPswdSalt);
    
    /**
     * 重置会员的登录密码
     *
     * @param id 会员ID
     * @param newEncryptPswd 更新的新密码,加密后的
     * @param newPswdSalt 更新密码使用的盐
     * @return
     */
    int resetPswd(long id, String newEncryptPswd, String newPswdSalt);
    
    /**
     * 会员总数
     *
     * @return
     */
    long count();
    
    /**
     * 统计指定日期范围内会员注册的数量
     *
     * @param start 开始日期
     * @param finish 结束日期
     * @return Key = YYYY-MM-DD, Value=注册数
     */
    TreeMap<String, Long> groupMemberForBirthDate(LocalDateTime start, LocalDateTime finish);
    
    /**
     * 分组统计不同状态的会员数量
     *
     * @return Key=Member.status, Value=会员数量
     */
    Map<MemberStatusEnum, Long> groupMemberForStatus();
    
    /**
     * 分组统计不同角色的会员数量
     *
     * @return Key=Member.mrole, Value=会员数量
     */
    Map<MemberRoleEnum, Long> groupMemberForRole();
    
    /**
     * 分组统计不同组的会员数量
     *
     * @return Key=Member.mgroup, Value=会员数量
     */
    Map<MemberGroupEnum, Long> groupMemberForGroup();
}